/*
 * Player.cpp
 *
 *  Created on: Oct 13, 2011
 *	Created by: Devin Manno
 *  Updated by: Devin Manno, Nick James
 *	Last Update: Oct 27, 2011
 */

#include "Player.h"
/*
 * setupPlayer
 * Description: Populates attacks vector with all possible attacks a player can use.
 * 		Also sets unlockAttacks vector to false because these attacks havent been learned
 * Pre: none
 * Post: Character's attacks vector is full of potential moves
 * 	 based on CharClass
 * Returns: none
 */

void Player::setupPlayer()  {
	// TODO game balance, prompt player for stat allocation upon new character creation to assign playerStats

	// add a player's special attacks and unlocks first one
	// the following attacks are mainly place holders to test but they can be in the
	// final project if you like
	switch(characterClass){
		case WARRIOR:
			attacks.push_back(AttackType("Bash", 100, 15));	// this is element 1 in attacks vector
			attacks.push_back(AttackType("Ground Slam",150,25)); 
			attacks.push_back(AttackType("Fire Breath",170,35)); 
			attacks.push_back(AttackType("Hell Rain",250,60));
			
			// unlocks first special move
			unlockedAttacks.push_back(true);
			// set new moves to locked
		       	for(unsigned int i = 2; i < attacks.size(); i++)
				unlockedAttacks.push_back(false);	
			break;
		case WIZARD:
			attacks.push_back(AttackType("Fireball", 125, 15));
			attacks.push_back(AttackType("Abra Kadabra",0,0)); // this is element 1 in attacks vector
			attacks.push_back(AttackType("Lightning Ball",0,0)); 
			attacks.push_back(AttackType("Soul steal",0,0)); 
		       	
			// unlocks first special move
			unlockedAttacks.push_back(true);
			// set new moves to locked
			for(unsigned int i = 2; i < attacks.size(); i++)
				unlockedAttacks.push_back(false);	
			break;
		case RANGER:
			attacks.push_back(AttackType("Volley", 110, 15));
			attacks.push_back(AttackType("Super Shot",0,0)); // this is element 1 in attacks vector
			attacks.push_back(AttackType("Rope of Doom",0,0)); 
			attacks.push_back(AttackType("Rain of 1000 Bullets",0,0)); 

			// unlocks first special move
			unlockedAttacks.push_back(true);
			// set new moves to locked
		       	for(unsigned int i = 2; i < attacks.size(); i++)
				unlockedAttacks.push_back(false);	
			break;
	}

}

Player::~Player() {
	// TODO Auto-generated destructor stub
}

// getters
/*
 * getClassName
 * Description: Returns the name of the class
 * Pre: none
 * Post: none
 * Returns: a string naming the class
 */

std::string Player::getClassName() const{
	return "Player";
}
/*
 * getPlayerStats
 * Description: gets the character's stats
 * Pre: none
 * Post: none
 * Returns: the characters stats
 */
const PlayerStats &Player::getPlayerStats() const{
	return playerStats;
}

// setters

/*
 * pickupItem
 * Description: the player equips an item
 * Pre: item is an equippable item
 * Post: any stat bonuses provided by item are added to the player's stats.
 * 	If the player already has an item of the same type equipped, the equipped
 * 	item is dropped.
 * 	Returns: none
 */
bool Player::equip(EquipmentType* item, std::string &errorMsg){
	
	int slotNum = item->getItemType();
	
	if(equipment[slotNum] != 0)
	{
		errorMsg = "Slot not empty.  Must dequip first.";
		return false;
	}
	
	int player_agility         = playerStats.getAgility();
	int player_strength        = playerStats.getStrength();
	int player_intelligence    = playerStats.getIntelligence();
	int player_concentration   = playerStats.getConcentration();
	int player_maxActionPoints = playerStats.getMaxActionPoints();
	int player_maxHitPoints    = playerStats.getMaxHitPoints();
	
	int item_agility         = item->getItemStats().getAgility();
	int item_strength        = item->getItemStats().getStrength();
	int item_intelligence    = item->getItemStats().getIntelligence();
	int item_concentration   = item->getItemStats().getConcentration();
	int item_maxActionPoints = item->getItemStats().getMaxActionPoints();
	int item_maxHitPoints    = item->getItemStats().getMaxHitPoints();
	
	int new_agility         = player_agility         + item_agility;
	int new_strength        = player_strength        + item_strength;
	int new_intelligence    = player_intelligence    + item_intelligence;
	int new_concentration   = player_concentration   + item_concentration;
	int new_maxActionPoints = player_maxActionPoints + item_maxActionPoints;
	int new_maxHitPoints    = player_maxHitPoints    + item_maxHitPoints;
	
	playerStats.setStats(new_agility, new_strength, new_intelligence, new_concentration, new_maxActionPoints, new_maxHitPoints);		
	
	equipment[slotNum] = item;
	
	return true;
}

/*
 * dequip
 * Description: the player drops an item (stops using the item)
 * Pre: itemID is an objectID of an item that the player is using
 * Post: any stat bonuses provided by item are removed from the player's stats.
 * 	the player can equip a new item of "item"'s type.
 * Returns: The item the player dequipped
 */
bool Player::dequip(EquipmentType* item, std::string &errorMsg){
	
	int slotNum = item->getItemType();
	
	if(equipment[slotNum] == 0)
	{
		errorMsg = "Slot already empty.";
		return false;
	}
		
	int player_agility         = playerStats.getAgility();
	int player_strength        = playerStats.getStrength();
	int player_intelligence    = playerStats.getIntelligence();
	int player_concentration   = playerStats.getConcentration();
	int player_maxActionPoints = playerStats.getMaxActionPoints();
	int player_maxHitPoints    = playerStats.getMaxHitPoints();
	
	int item_agility         = item->getItemStats().getAgility();
	int item_strength        = item->getItemStats().getStrength();
	int item_intelligence    = item->getItemStats().getIntelligence();
	int item_concentration   = item->getItemStats().getConcentration();
	int item_maxActionPoints = item->getItemStats().getMaxActionPoints();
	int item_maxHitPoints    = item->getItemStats().getMaxHitPoints();
	
	int new_agility         = player_agility         - item_agility;
	int new_strength        = player_strength        - item_strength;
	int new_intelligence    = player_intelligence    - item_intelligence;
	int new_concentration   = player_concentration   - item_concentration;
	int new_maxActionPoints = player_maxActionPoints - item_maxActionPoints;
	int new_maxHitPoints    = player_maxHitPoints    - item_maxHitPoints;
	
	playerStats.setStats(new_agility, new_strength, new_intelligence, new_concentration, new_maxActionPoints, new_maxHitPoints);		
	
	equipment[slotNum] = 0;     // set to NULL
	
	return true;
}

/*
 * usePotion
 * Description: Player uses a health potion to restore the player's health
 * Pre: Player has a health potion
 * Post: Player's health is increased by 75% of max
 * Returns: a string describing the effect of using the health potion
 */
bool Player::usePotion(Potion *potion){
	float hpp = potion->getHitPointPercentage();
	float app = potion->getActionPointPercentage();

	// add hit points if potion contains a buff to hit points
	int maxhp = playerStats.getMaxHitPoints();	// current max hit points
	int curhp = playerStats.getHitPoints();		// current hit points
	int addhp = maxhp * hpp;			// hit points to add to player's current hit points

	if((addhp + curhp) > maxhp)
			playerStats.setHitPoints(maxhp);
		else
			playerStats.setHitPoints(addhp + curhp);

	// add action points if potion contains a buff to action points
	int maxap = playerStats.getMaxActionPoints();	// current max action points
	int curap = playerStats.getActionPoints();	// current action points
	int addap = maxap * app;			// action points to add to a player's current action points

	if((addap + curap) > maxap)
		playerStats.setActionPoints(maxap);
	else
		playerStats.setActionPoints(addap + curap);

	return true;   					//controller should delete potion pointer on success.
}

/*
 * increaseExp
 * Description: Increases players experience points 
 * Pre: Player has a x amount of experience points
 * Post: Player's experience points boosted by boost amoung
 * Returns: bool that indicates whether or not new abilities were unlocked
 */
/*
bool Player::increaseExp(int boost){
	int newExp = playerStats.getExp() + boost;
	playerStats.setExp(newExp);
	return unlock();
}
*/

/*
 * unlock 
 * Description: unlocks new abilites for player 
 * Pre: takes level of player to determine if unlocked anything
 * Post: If players experience reaches certain level, 
 * 	they unlock a new ability
 * Returns: bool that indicates whether or not new abilities were unlocked
 */
/*
bool Player::unlock(int level){
}
*/
